<?php
// @formatter:off
/**
 * @file WCRuleAction.php
 * @author Alejandro Dario Simi
 * @date $Date: 2013-06-16 23:56:49 +0000 (Sun, 16 Jun 2013) $
 *
 * $Id: WCRuleAction.php 73 2013-06-16 23:56:49Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/tags/wcomix-1.0-BETA1/includes/WCRuleAction.php $
 */
// @formatter:on

require_once "{$wcPaths["includes-directory"]}/search/WCSearch.php";

/**
 * @class WCRuleAction
 * @abstract
 * @author Alejandro Dario Simi
 *
 */
abstract class WCRuleAction implements WCSearchIndexable, WCPreviews {
	/**
	 * @var WCGroup
	 */
	protected $_conflict;
	protected $_group;
	protected $_ruleId;
	protected $_rule = false;
	protected $_id;
	protected $_info = array();
	protected $_indexed;
	protected $_name;
	protected $_ok;
	protected $_type;
	protected $_ignoreConfics = false;

	/**
	 * @var WCConnection
	 */
	protected $_db;
	protected $_dbprefix;

	public function __construct($ruleId, $actionId, WCGroup &$group) {
		global $wcDatabaseAccess;

		$this->_db = WCConnection::Instance();
		$this->_dbprefix = $wcDatabaseAccess['prefix'];

		$this->_group = $group;
		$this->_ruleId = $ruleId;
		$this->_id = $actionId;
		$this->_name = $actionId;
		$this->_conflict = false;
		$this->_ok = false;
		$this->_type = false;

		$this->mainLoad();
		$this->load();
	}
	//
	// Public Methods
	public function __get($name) {
		return isset($this->_info[$name]) ? $this->_info[$name] : null;
	}
	public function __set($name, $value) {
		$out = false;

		if($this->ok()) {
			$this->_info[$name] = $value;

			$stmt = false;
			$stmtID = __CLASS__."::".__FUNCTION__;
			if($this->_db->has($stmtID)) {
				$stmt = $this->_db->get($stmtID);
			} else {
				$query = "update  {$this->_dbprefix}rule_actions\n";
				$query .= "set     rel_ra_info = :info\n";
				$query .= "where   rel_ra_rule   = :rule\n";
				$query .= " and    rel_ra_type   = :type\n";
				$query .= " and    rel_ra_action = :action\n";

				$stmt = $this->_db->prepare($stmtID, $query);
			}

			$params = array(
				":info" => serialize($this->_info),
				":rule" => $this->_ruleId,
				":type" => $this->_type,
				":action" => $this->_id
			);

			$stmt->execute($params);
		}

		return $out;
	}
	public function conflict() {
		return $this->_conflict;
	}
	public function generatePreviews() {
		$out = false;

		return $out;
	}
	public function group() {
		return $this->_group;
	}
	public function hasPreview() {
		return false;
	}
	public function hasPreviews() {
		return false;
	}
	public function id() {
		return $this->_id;
	}
	public function ignoreConfics() {
		return $this->_ignoreConfics;
	}
	public function indexed($value = null) {
		if($value !== null) {
			$stmt = false;
			$stmtID = __CLASS__."::".__FUNCTION__;
			if($this->_db->has($stmtID)) {
				$stmt = $this->_db->get($stmtID);
			} else {
				$query = "update  {$this->_dbprefix}rule_actions\n";
				$query .= "set     rel_ra_indexed = :indexed\n";
				$query .= "where   rel_ra_rule    = :rule\n";
				$query .= " and    rel_ra_type    = :type\n";
				$query .= " and    rel_ra_action  = :action\n";

				$stmt = $this->_db->prepare($stmtID, $query);
			}

			$params = array(
				":rule" => $this->_ruleId,
				":type" => $this->_type,
				":action" => $this->_id,
				":indexed" => $value ? "Y" : "N"
			);

			if($stmt->execute($params) && $stmt->rowCount() > 0) {
				$this->_indexed = $value;
			}
		}

		return $this->_indexed;
	}
	public function info() {
		return $this->_info;
	}
	public function name() {
		return $this->_name;
	}
	public function ok() {
		return $this->_ok;
	}
	public function preview() {
		return "";
	}
	public function previews() {
		return array();
	}
	/**
	 * @return WCRule
	 */
	public function rule() {
		if(!$this->_rule) {
			global $wcRulesHolder;

			$this->_rule = @$wcRulesHolder->item($this->_ruleId, $this->_group);
			if(!$this->_rule || !$this->_rule->ok()) {
				$this->_rule = false;
			}
		}

		return $this->_rule;
	}
	public function run() {
		die(__CLASS__."::".__FUNCTION__."() Subclass Resposabillity\n");
		return array();
	}
	/**
	 * This method reload all object data.
	 */
	public function reload() {
		//
		// Resetting values.
		// @{
		$this->_conflict = false;
		$this->_name = $this->_id;
		$this->_ok = false;
		$this->_type = false;
		$this->_rule = false;
		// @}
		//
		// Basic data loading.
		$this->mainLoad();
		//
		// Specific data loading.
		$this->load();
	}
	public function remove() {
		if($this->type()) {
			$this->rule()->indexed(false);

			$stmt = null;
			$stmtID = __CLASS__."::".__FUNCTION__;
			if($this->_db->has($stmtID)) {
				$stmt = $this->_db->get($stmtID);
			} else {
				$query = "delete from {$this->_dbprefix}rule_actions\n";
				$query .= "where       rel_ra_action = :id";
				$stmt = $this->_db->prepare(__CLASS__."::".__FUNCTION__, $query);
			}

			$stmt->execute(array(":id" => $this->id()));

			return $this->removeSpecific();
		} else {
			die(__CLASS__."::".__FUNCTION__."() Not type set");
			return false;
		}
	}
	public function setIgnoreConfics($ignore) {
		$this->_ignoreConfics = $ignore;
		return $this->ignoreConfics();
	}
	public function setConflict($status) {
		if($status != $this->_conflict) {
			//
			//
			// @{
			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__;
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "update  {$this->_dbprefix}rule_actions\n";
				$query .= "set     rel_ra_conflict = :conflict\n";
				$query .= "where   rel_ra_rule     = :rule\n";
				$query .= " and    rel_ra_action   = :action\n";
				$stmt = $this->_db->prepare($stmtId, $query);
			}
			// @}
			//
			//
			// @{
			$params = array(
				":rule" => $this->_ruleId,
				":action" => $this->_id,
				":conflict" => $status ? "Y" : "N"
			);
			$stmt->execute($params);
			// @}
			if($status) {
				$this->rule()->conflict = true;
			}
			//
			//
			return $this->conflict();
		}
	}
	/**
	 * This method allows to change action's name.
	 *
	 * @param string $name Name to be set.
	 * @return string Returns action name.
	 */
	public function setName($name) {
		//
		// Creating a statement to alter action's name.
		// @{
		$stmt = null;
		$stmtId = __CLASS__."::".__FUNCTION__;
		if($this->_db->has($stmtId)) {
			$stmt = $this->_db->get($stmtId);
		} else {
			$query = "update  {$this->_dbprefix}rule_actions\n";
			$query .= "set     rel_ra_name   = :newname\n";
			$query .= "where   rel_ra_rule   = :rule\n";
			$query .= " and    rel_ra_action = :action\n";
			$stmt = $this->_db->prepare($stmtId, $query);
		}
		// @}
		//
		// Changing name.
		// @{
		$params = array(
			":rule" => $this->_ruleId,
			":action" => $this->_id,
			":newname" => $name
		);
		if($stmt->execute($params) && $stmt->rowCount() > 0) {
			//
			// At this point, name was changed therefore the object is
			// reloaded.
			$this->reload();
		}
		// @}
		//
		// Returning final name.
		return $this->name();
	}
	public function type() {
		return $this->_type;
	}
	//
	// Protected Methods
	protected function load() {
		die(__CLASS__."::".__FUNCTION__."() Subclass Resposabillity\n");
	}
	protected function mainLoad() {
		$stmt = null;
		$stmtId = __CLASS__."::".__FUNCTION__;
		if($this->_db->has($stmtId)) {
			$stmt = $this->_db->get($stmtId);
		} else {
			$query = "select  *\n";
			$query .= "from    {$this->_dbprefix}rule_actions\n";
			$query .= "where   rel_ra_rule   = :rule\n";
			$query .= " and    rel_ra_action = :action\n";
			$stmt = $this->_db->prepare($stmtId, $query);
		}

		$params = array(
			":rule" => $this->_ruleId,
			":action" => $this->_id
		);

		if($stmt->execute($params) && $stmt->rowCount() > 0) {
			$row = $stmt->fetch();

			$this->_type = $row["rel_ra_type"];
			$this->_name = $row["rel_ra_name"];
			$this->_indexed = $row["rel_ra_indexed"] == "Y";
			$this->_conflict = $row["rel_ra_conflict"] == "Y";
			$this->_info = unserialize($row["rel_ra_info"]);
		}
	}
	protected function removeSpecific() {
		die(__CLASS__."::".__FUNCTION__."() Subclass Resposabillity\n");
		return false;
	}
	//
	// Public class methods.
	public static function Sort($a, $b) {
		return self::NameSort($a, $b);
	}
	/**
	 * This is a sorting method based on action names and it can be used on
	 * usort and uasort functions.
	 *
	 * @param WCRuleAction $a Left operand.
	 * @param WCRuleAction $b Right operand.
	 * @return boolean Returns true when the id of $a is greater than
	 * $b's.
	 */
	public static function IdSort(WCRuleAction &$a, WCRuleAction &$b) {
		return $a->id() > $b->id();
	}
	/**
	 * This is a sorting method based on action names and it can be used on
	 * usort and uasort functions.
	 *
	 * @param WCRuleAction $a Left operand.
	 * @param WCRuleAction $b Right operand.
	 * @return boolean Returns true when the name of $a is greater than
	 * $b's.
	 */
	public static function NameSort(WCRuleAction &$a, WCRuleAction &$b) {
		return $a->name() > $b->name();
	}
}
?>